package com.wlsk.license.common.execl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.wlsk.license.common.exception.BusinessException;
import com.wlsk.license.common.result.Result;
import com.wlsk.license.common.utils.PathFileUtils;
import com.wlsk.license.common.utils.ValidationUtils;
import com.wlsk.license.dto.request.feign.GetOssObjectUrlReqDto;
import com.wlsk.license.dto.response.feign.OssObjectInfoResultDto;
import com.wlsk.license.service.feign.PlatOssFeignClient;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.util.Objects;

/**
 * <p>@Description : Excel导出服务</p>
 * <p>@Author : Zhangbin.Liu </p>
 * <p>@Date : 2025/02/18 16:53 </p>
 */
public abstract class AbstractBaseExcelExportService<DATA, PARAM> implements ExcelExportService {

    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * OSS上传位置
     */
    private static final int POSITION = 15;

    @Resource
    private PlatOssFeignClient platOssFeignClient;

    /**
     * 文件名称
     *
     * @param param
     * @return
     */
    protected abstract String getName(PARAM param);

    protected String getFilename(PARAM param) {
        return this.getName(param) + "_.xls";
    }

    protected String getPath() {
        return PathFileUtils.getPath();
    }

    protected String getLocalFileName(PARAM param, String path) {
        return path.concat(getFilename(param));
    }

    /**
     * 上传OSS，返回下载链接
     */
    protected String uploadOss(String localFileName) {
        return uploadOss(localFileName, null);
    }

    /**
     * 上传OSS，返回下载链接
     *
     * @param localFileName 本地文件名
     * @param customFileName 自定义文件名（可选）
     * @return 下载链接
     */
    protected String uploadOss(String localFileName, String customFileName) {
        FileInputStream inputStream = null;
        File file = null;
        FileItem fileItem = null;
        String url = "";
        try {
            file = new File(localFileName);
            inputStream = new FileInputStream(file);
            // 如果提供了自定义文件名，则使用自定义文件名，否则使用原文件名
            String uploadFileName = customFileName != null ? customFileName : file.getName();
            fileItem = new DiskFileItem("ossObject", "application/vnd.ms-excel", true, uploadFileName, (int) file.length(), file.getParentFile());
            fileItem.getOutputStream().write(IoUtil.readBytes(inputStream));
            CommonsMultipartFile multipartFile = new CommonsMultipartFile(fileItem);
            Result<OssObjectInfoResultDto> result = platOssFeignClient.uploadOssObject(multipartFile, POSITION);
            log.info("导出Excel数据调用上传服务响应:{}", result);
            ValidationUtils.isTrue(result.isSuccess(), result.getMsg());
            result = platOssFeignClient.getOssObjectUrl(new GetOssObjectUrlReqDto(result.getData().getId()));
            log.info("导出数据获取文件下载地址响应:{}", result);
            ValidationUtils.isTrue(result.isSuccess(), "导出异常");
            url = result.getData().getUrl();
        } catch (Exception e) {
            log.error("导出数据调用通用上传服务错误:{}", e.getMessage(), e);
            throw new BusinessException("导出错误");
        } finally {
            if (Objects.nonNull(fileItem)) {
                fileItem.delete();
            }
            String path = StringUtils.substringBeforeLast(localFileName, File.separator);
            IoUtil.close(inputStream);
            FileUtil.del(path);
        }
        return url;
    }

    /**
     * 删除目录
     */
    protected void deletePath(String path) {
        File pathDir = new File(path);
        if (pathDir.exists()) {
            pathDir.delete();
        }
    }

    /**
     * 删除本地文件和目录
     *
     * @param localFileName
     */
    protected void deleteLocalFile(String localFileName) {
        File file = new File(localFileName);
        if (file.exists()) {
            file.delete();
        }
        String path = StringUtils.substringBeforeLast(localFileName, File.separator);
        this.deletePath(path);
    }


}